{-# OPTIONS -Wall #-}

--------------------------------------------------------------------------------
-- |
-- Module      :  Ochre.Compiler.VarId
-- Copyright   :  (c) Stephen Tetley 2012
-- License     :  BSD3
--
-- Maintainer  :  stephen.tetley@gmail.com
-- Stability   :  unstable
-- Portability :  GHC
--
-- Variable ids annotated with type and declaration site 
-- (local or global).
--
-- Declaration sites are needed to generate names. 
--
--------------------------------------------------------------------------------

module Ochre.Compiler.VarId
  (

    Decimal

  , RateId(..)
  , VarId(..)
  , ppVarId
  , varName

  , PrimId(..)

  , varRate

  
  ) where



import Text.PrettyPrint.HughesPJ                -- package: pretty

import Data.Fixed


type Decimal = Fixed E9                


-- | Decl site used to determine when to prefix the var name with
-- a @g@. 
--
data RateId = I_RATE | K_RATE | A_RATE
  deriving (Enum,Eq,Ord,Show)

-- TODO - names should probably be integers, with decl-site and
-- type we can then synthesize String names.
--


data VarId = Global  { var_rate  :: RateId
                     , var_name  :: String
                     }
           | Local   { var_rate  :: RateId
                     , var_num   :: Int
                     }
           | DeclVar { var_rate  :: RateId
                     , var_name  :: String
                     }
  deriving (Eq,Ord,Show)

-- Note we need something better for Decl vars...

varRate :: VarId -> RateId
varRate = var_rate

rateName :: RateId -> Char
rateName I_RATE = 'i'
rateName K_RATE = 'k'
rateName A_RATE = 'a'

-- | Identifiers whose type cannot be rendered to Csound 
-- prim-types get name mangled.
--
varName :: VarId -> String
varName (Global _ ss)    = ss
varName (Local ri i)     = rateName ri : 'Z' : show i
varName (DeclVar _ ss)   = ss

ppVarId :: VarId -> Doc
ppVarId = text . varName

-- | Identifier for opcodes - never alpha renamed.
newtype PrimId = PrimId { prim_name   :: String }
  deriving (Eq,Ord,Show)
